/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.client.proxy;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;

import org.creativor.rayson.api.NetworkException;
import org.creativor.rayson.api.Protocol;
import org.creativor.rayson.client.transport.ConnectionPool;
import org.creativor.rayson.client.transport.http.ClientHttpRequest;
import org.creativor.rayson.client.transport.http.HttpConnection;
import org.creativor.rayson.share.transport.http.HttpRequestLine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An {@link InvocationHandler} used to invoke RPC invocation.This role will
 * manipulate transport layer directly.
 * 
 * @author creativor
 */
class RpcInvocationHandler implements InvocationHandler {
	private static final String METHOD_URI_SPLITER = "/";
	private static Logger LOG = LoggerFactory
			.getLogger(RpcInvocationHandler.class);
	private final InetSocketAddress serverAddr;
	private final Class<? extends Protocol> protocol;

	/**
	 * @param serverAddr
	 * @param protocol
	 */
	RpcInvocationHandler(final InetSocketAddress serverAddr,
			final Class<? extends Protocol> protocol) {
		this.serverAddr = serverAddr;
		this.protocol = protocol;
	}

	@Override
	public Object invoke(final Object proxy, final Method method,
			final Object[] args) throws Throwable {
		// FIXME: Ignore Object build in methods.
		final HttpConnection conn;
		try {
			conn = ConnectionPool.getPool().getConnection(serverAddr);
		} catch (final IOException e) {
			throw new NetworkException(
					"Failed to get connection of remote server " + serverAddr,
					e);
		}
		final HttpRequestLine requestLine = new HttpRequestLine(
				protocol.getName() + METHOD_URI_SPLITER + method.getName());
		ClientHttpRequest httpRequest = new ClientHttpRequest(
				new HttpRequestLine("a.b.c/d"));
		final byte[] body = new byte[] { 1, 2, 3, 4, 5, 78, 56 };
		httpRequest.setBody(body);
		conn.send(httpRequest);
		for (int i = 0; i < 2000; i++) {
			httpRequest = new ClientHttpRequest(requestLine);
			httpRequest.setBody(new byte[] { 4, 5, (byte) i });
			conn.send(httpRequest);

		}
		return null;
	}
}
